﻿using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using Aspose.Cells;
using CCTool.Scripts.Manager;
using CCTool.Scripts.ToolManagers;
using CCTool.Scripts.ToolManagers.Extensions;
using CCTool.Scripts.ToolManagers.Managers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Polygon = ArcGIS.Core.Geometry.Polygon;
using Row = ArcGIS.Core.Data.Row;
using Table = ArcGIS.Core.Data.Table;

namespace CCTool.Scripts.UI
{
    /// <summary>
    /// Interaction logic for TownShip.xaml
    /// </summary>
    public partial class TownShip : ArcGIS.Desktop.Framework.Controls.ProWindow
    {
        // 工具设置标签
        readonly string toolSet = "TownShip";

        // 定义一个进度框
        private ProcessWindow processwindow = null;
        string tool_name = "镇区划定";

        public TownShip()
        {
            InitializeComponent();

            // 初始化参数选项
            textBaseFolderPath.Text = BaseTool.ReadValueFromReg(toolSet, "baseFolderPath");
            textTargetFolderPath.Text = BaseTool.ReadValueFromReg(toolSet, "targetFolderPath");
            cb_2021.IsChecked = BaseTool.ReadValueFromReg(toolSet, "is_2021").ToBool();

        }

        // 收集参数
        private RD GetParams()
        {
            RD rd = new RD();

            string baseFolderPath = textBaseFolderPath.Text;
            string targetFolderPath = textTargetFolderPath.Text;
            bool is_2021 = cb_2021.IsChecked.Value;

            // 写入参数
            rd.BaseFolderPath = baseFolderPath;
            rd.TargetFolderPath = targetFolderPath;
            rd.Is_2021 = is_2021;

            rd.DefGDB = $@"{Project.Current.DefaultGeodatabasePath}";
            rd.TemFC = $@"{rd.DefGDB}\tem_fc";
            rd.TemTable = $@"{rd.DefGDB}\tem_table";



            // 年度列表
            if (!is_2021)
            {
                rd.Years = [2021, 2022, 2023, 2024];
            }
            else
            {
                rd.Years = [2021];
            }


            // 保存参数
            BaseTool.WriteValueToReg(toolSet, "baseFolderPath", baseFolderPath);
            BaseTool.WriteValueToReg(toolSet, "targetFolderPath", targetFolderPath);
            BaseTool.WriteValueToReg(toolSet, "is_2021", is_2021);

            return rd;
        }

        #region   基础数据处理
        // 提取指定地类
        private async void btn_select_zddl_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【提取指定地类】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string dltb = $@"{rd.BaseFolderPath}\350524安溪县({year}).gdb\data\DLTB";

                        string zddl = $@"{rd.BaseFolderPath}\350524安溪县({year}).gdb\data\ZDDL";

                        string sql = $"CZCSXM IN ('201', '2021A', '202', '202A', '203', '203A') Or DLBM IN ('0508', '05H1', '0601', '0701', '0702','0809', '0810', '0810A', '08H1', '08H2', '08H2A', '09', '1001','1002', '1003', '1004', '1005', '1006','1007', '1008','1009','1107','1107A','1109')";
                        // 提取
                        Arcpy.Select(dltb, zddl, sql);
                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }
        #endregion   基础数据处理

        #region   数据生成
        // 生成初始范围zqcsfw
        private async void btn_create_csfw_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【生成初始范围zqcsfw】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string czcdyd = $@"{rd.BaseFolderPath}\350524安溪县({year}).gdb\data\CZCDYD";

                        string csfw = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb\安溪县zqcsfw";
                        // 复制模板
                        pw.AddMessageMiddle(0, $"     复制模板", Brushes.Gray);
                        string bzModel = year switch
                        {
                            2021 => "千分之一",
                            2022 => "千分之一",
                            2023 => "千分之一",
                            2024 => "千分之一",
                            _ => throw new Exception("请选择正确的年份")
                        };
                        string model = $@"{rd.BaseFolderPath}\标准数据库_{bzModel}.gdb\zqcsfw";
                        Arcpy.CopyFeatures(model, csfw);


                        pw.AddMessageMiddle(0, $"     筛选202、202A", Brushes.Gray);
                        string sql = $"CZCLX IN ('202', '202A')";
                        // 提取
                        Arcpy.Select(czcdyd, rd.TemFC, sql);
                        // 更新数据
                        Arcpy.Append(rd.TemFC, csfw);


                        // 计算字段值
                        pw.AddMessageMiddle(0, $"     计算字段", Brushes.Gray);
                        Arcpy.CalculateField(csfw, "SMC", "'福建省'");
                        Arcpy.CalculateField(csfw, "JSMJ", "round(!Shape_Area!,2)");
                        Arcpy.CalculateField(csfw, "BZ", "''");
                        // 空间更新
                        pw.AddMessageMiddle(0, $"     空间更新", Brushes.Gray);
                        string xzq = $@"{rd.BaseFolderPath}\350524安溪县({year}).gdb\data\XZQ";

                        ComboTool.SetValueBySpatialPosition(csfw, xzq, [["XZQDM", "XZQDM"], ["XZQMC", "XZQMC"]]);


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }

        }
        // 生成实体地域zqstdy
        private async void btn_create_stdy_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【生成实体地域zqstdy】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);
                        string dltb = $@"{rd.BaseFolderPath}\350524安溪县({year}).gdb\data\DLTB";
                        string ori_zddl = $@"{rd.BaseFolderPath}\350524安溪县({year}).gdb\data\ZDDL";

                        string csfw = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb\安溪县zqcsfw";
                        string zqstdy = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb\安溪县zqstdy";
                        // 复制模板
                        string bzModel = year switch
                        {
                            2021 => "十万分之一",
                            2022 => "十万分之一",
                            2023 => "十万分之一",
                            2024 => "千分之一",
                            _ => throw new Exception("请选择正确的年份")
                        };

                        pw.AddMessageMiddle(0, $"     提取矢量数据", Brushes.Gray);
                        string model = $@"{rd.BaseFolderPath}\标准数据库_{bzModel}.gdb\zqstdy";
                        Arcpy.CopyFeatures(model, zqstdy);

                        // 补充初始范围内的数据
                        string clip2 = $@"{rd.DefGDB}\clip2";
                        Arcpy.Clip(dltb, csfw, clip2);
                        string erase2 = $@"{rd.DefGDB}\erase2";
                        Arcpy.Erase(clip2, ori_zddl, erase2);
                        // 复制，追加
                        string zddl = $@"{rd.DefGDB}\zddl2";
                        Arcpy.CopyFeatures(ori_zddl, zddl);
                        Arcpy.Append(erase2, zddl);


                        pw.AddMessageMiddle(0, $"     按前一版方案提取指定地类", Brushes.Gray);
                        // 空间连接
                        string lastSt = $@"{rd.TargetFolderPath}_备用\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb\安溪县zqstdy";
                        string spatialJoin = $@"{rd.DefGDB}\_spatialJoin";

                        string block = $"DLBM \"地类编码\" true true false 20 Text 0 0,First,#,{zddl},DLBM,0,4;DLMC \"地类名称\" true true false 60 Text 0 0,First,#,{zddl},DLMC,0,59;JCWDM \"居村委代码\" true true false 19 Text 0 0,First,#,{zddl},ZLDWDM,0,18;JCWMC \"居村委名称\" true true false 255 Text 0 0,First,#,{zddl},ZLDWMC,0,254;RepeatNum \"迭代次数\" true true false 20 Text 0 0,First,#,{lastSt},RepeatNum,0,19";
                        Arcpy.SpatialJoin(zddl, lastSt, spatialJoin, block);
                        // 提取
                        string select2 = $@"{rd.DefGDB}\select2";
                        Arcpy.Select(spatialJoin, select2, "RepeatNum IS NOT NULL");

                        // 空间更新
                        pw.AddMessageMiddle(0, $"     空间更新XZQDM和XZQMC", Brushes.Gray);
                        string xzq = $@"{rd.BaseFolderPath}\350524安溪县({year}).gdb\data\XZQ";
                        string spatialJoin2 = $@"{rd.DefGDB}\_spatialJoin2";
                        string block2 = $"DLBM \"地类编码\" true true false 20 Text 0 0,First,#,{select2},DLBM,0,19;DLMC \"地类名称\" true true false 60 Text 0 0,First,#,{select2},DLMC,0,59;JCWDM \"居村委代码\" true true false 19 Text 0 0,First,#,{select2},JCWDM,0,18;JCWMC \"居村委名称\" true true false 255 Text 0 0,First,#,{select2},JCWMC,0,254;RepeatNum \"迭代次数\" true true false 20 Text 0 0,First,#,{select2},RepeatNum,0,19;XZQDM \"行政区代码\" true true false 9 Text 0 0,First,#,{xzq},XZQDM,0,8;XZQMC \"行政区名称\" true true false 100 Text 0 0,First,#,{xzq},XZQMC,0,99";
                        Arcpy.SpatialJoin(select2, xzq, spatialJoin2, block2);

                        pw.AddMessageMiddle(0, $"     更新至模板", Brushes.Gray);
                        // 更新数据
                        Arcpy.Append(spatialJoin2, zqstdy);
                        // 补充字段计算
                        Arcpy.CalculateField(zqstdy, "SMC", "'福建省'");
                        // 删除中间数据
                        Arcpy.Delect(spatialJoin);
                        Arcpy.Delect(spatialJoin2);
                        Arcpy.Delect(select2);
                        Arcpy.Delect(clip2);
                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 生成增减图斑
        private async void btn_create_zjtb_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【生成增减图斑】", Brushes.Blue);


                    foreach (var year in rd.Years)
                    {
                        // 2021年没有减减图斑，不处理
                        int year_init = year;
                        int yeart_last = year_init - 1;
                        if (year_init == 2021)
                        {
                            continue;
                        }


                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);
                        string stdy_init = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year_init}\1矢量数据\350524安溪县.gdb\安溪县zqstdy";
                        string stdy_last = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{yeart_last}\1矢量数据\350524安溪县.gdb\安溪县zqstdy";


                        string tem_fc = $@"{rd.DefGDB}\tem_fc";
                        string tem_fc2 = $@"{rd.DefGDB}\tem_fc2";

                        string zjtb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb\安溪县zqstdyzjtb";
                        string jstb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb\安溪县zqstdyjstb";

                        // 复制模板
                        string model_zjtb = $@"{rd.BaseFolderPath}\标准数据库_千分之一.gdb\zqstdyzjtb";
                        Arcpy.CopyFeatures(model_zjtb, zjtb);
                        string model_jstb = $@"{rd.BaseFolderPath}\标准数据库_千分之一.gdb\zqstdyjstb";
                        Arcpy.CopyFeatures(model_jstb, jstb);

                        // 增加图斑
                        Arcpy.Erase(stdy_init, stdy_last, tem_fc);
                        Arcpy.MultipartToSinglepart(tem_fc, tem_fc2);
                        Arcpy.Append(tem_fc2, zjtb);
                        // 减少图斑
                        Arcpy.Erase(stdy_last, stdy_init, tem_fc);
                        Arcpy.MultipartToSinglepart(tem_fc, tem_fc2);
                        Arcpy.Append(tem_fc2, jstb);

                        // 更新字段_增加图斑
                        Arcpy.CalculateField(zjtb, "TBZJ", "'迭代纳入'");
                        Arcpy.CalculateField(zjtb, "BZ", "''");

                        // 更新字段_增加图斑
                        Arcpy.CalculateField(jstb, "TBSC", "'三调图斑变化'");
                        Arcpy.CalculateField(jstb, "BZ", "''");
                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 生成行政界线
        private async void btn_create_xzjx_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【生成行政界线】", Brushes.Blue);

                    string xzjx = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县2021\1矢量数据\350524安溪县.gdb\安溪县xzjx";
                    string xzq = $@"{rd.BaseFolderPath}\350524安溪县(2021).gdb\data\XZQ";

                    // 复制模板
                    string model_xzjx = $@"{rd.BaseFolderPath}\标准数据库_千分之一.gdb\xzjx";
                    Arcpy.CopyFeatures(model_xzjx, xzjx);

                    // 追加
                    Arcpy.Append(xzq, xzjx);

                    // 字段计算
                    Arcpy.CalculateField(xzjx, "QXMC", "'安溪县'");

                    Arcpy.RepairGeometry(xzjx);

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 生成最小统计单元
        private async void btn_create_zxtjdy_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【生成最小统计单元】", Brushes.Blue);

                    string zxtjdy = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县2021\1矢量数据\350524安溪县.gdb\安溪县zxtjdy";
                    string xzjx = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县2021\1矢量数据\350524安溪县.gdb\安溪县xzjx";

                    string cjdcq = $@"{rd.BaseFolderPath}\350524安溪县(2021).gdb\data\CJDCQ";

                    pw.AddMessageMiddle(0, $"     提取矢量数据", Brushes.Gray);

                    // 复制模板
                    string model_zxtjdy = $@"{rd.BaseFolderPath}\标准数据库_千分之一.gdb\zxtjdy";
                    Arcpy.CopyFeatures(model_zxtjdy, zxtjdy);

                    // 村级行政区图层字段修改
                    Arcpy.CopyFeatures(cjdcq, rd.TemFC);
                    Arcpy.AlterField(rd.TemFC, "ZLDWDM", "JCWDM");
                    Arcpy.AlterField(rd.TemFC, "ZLDWMC", "JCWMC");

                    // 追加
                    Arcpy.Append(rd.TemFC, zxtjdy);

                    // 字段计算
                    Arcpy.CalculateField(zxtjdy, "BZ", "''");


                    pw.AddMessageMiddle(0, $"     空间赋值行政区代码名称", Brushes.Gray);
                    // 空间赋值：行政区代码名称
                    ComboTool.SetValueBySpatialPosition(zxtjdy, xzjx, [["XZQDM", "XZQDM"], ["XZQMC", "XZQMC"]]);

                    Arcpy.RepairGeometry(zxtjdy);

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }


        // 生成镇区范围
        private async void btn_create_zqfw_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【生成镇区范围】", Brushes.Blue);

                    string zxtjdy = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县2021\1矢量数据\350524安溪县.gdb\安溪县zxtjdy";
                    string zqstdy = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县2021\1矢量数据\350524安溪县.gdb\安溪县zqstdy";
                    string zqfw = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县2021\1矢量数据\350524安溪县.gdb\安溪县zqfw";
                    string zddl = $@"{rd.BaseFolderPath}\350524安溪县(2021).gdb\data\ZDDL";

                    pw.AddMessageMiddle(0, $"     提取矢量数据", Brushes.Gray);

                    // 复制模板
                    string model_zqfw = $@"{rd.BaseFolderPath}\标准数据库_千分之一.gdb\zqfw";
                    Arcpy.CopyFeatures(model_zqfw, zqfw);


                    pw.AddMessageMiddle(0, $"     统计实体地域面积指标", Brushes.Gray);
                    // 统计各行政村面积指标
                    // 实体地域
                    string table_stdy = $@"{rd.DefGDB}\table_stdy";
                    Arcpy.TabulateIntersection(zxtjdy, ["JCWMC"], zqstdy, table_stdy, "");
                    Arcpy.AlterField(table_stdy, "AREA", "STDYMJ", "实体地域面积");

                    pw.AddMessageMiddle(0, $"     统计指定地类面积指标", Brushes.Gray);
                    // 指定地类
                    string table_zddl = $@"{rd.DefGDB}\table_zddl";
                    Arcpy.TabulateIntersection(zxtjdy, ["JCWMC"], zddl, table_zddl, "");
                    Arcpy.AlterField(table_zddl, "AREA", "ZDDLMJ", "指定地类面积");

                    pw.AddMessageMiddle(0, $"     连接面积指标", Brushes.Gray);
                    // 复制最小统计单元，并连接字段
                    Arcpy.CopyFeatures(zxtjdy, rd.TemFC);
                    Arcpy.JoinField(rd.TemFC, "JCWMC", table_stdy, "JCWMC", ["STDYMJ"]);
                    Arcpy.JoinField(rd.TemFC, "JCWMC", table_zddl, "JCWMC", ["ZDDLMJ"]);


                    pw.AddMessageMiddle(0, $"     字段计算", Brushes.Gray);
                    // 追加
                    Arcpy.Append(rd.TemFC, zqfw);

                    // 字段计算
                    Arcpy.CalculateField(zqfw, "SMC", "'福建省'");
                    Arcpy.CalculateField(zqfw, "MJZB", "!STDYMJ! / !ZDDLMJ!");
                    Arcpy.CalculateField(zqfw, "JCWMJ", "!Shape_Area!");
                    Arcpy.CalculateField(zqfw, "BHBZ", "''");
                    Arcpy.CalculateField(zqfw, "BZ", "''");

                    pw.AddMessageMiddle(0, $"     空间赋值：备注说明", Brushes.Gray);
                    // 空间赋值：备注说明
                    // 上一轮zqfw
                    string last_zqfw = $@"{rd.TargetFolderPath}_备用\350524安溪县\350524安溪县2021\1矢量数据\350524安溪县.gdb\安溪县zqfw";
                    ComboTool.SetValueBySpatialPosition(zqfw, last_zqfw, [["BZ", "BZ"]]);

                    // 导出最小统计单元面积数据表
                    ExportTable(zqfw, rd);


                    // 提取镇区范围
                    pw.AddMessageMiddle(0, $"     提取镇区范围", Brushes.Gray);
                    Arcpy.Select(zqfw, rd.TemFC, "MJZB > 0.5 Or BZ <> ''");
                    Arcpy.CopyFeatures(rd.TemFC, zqfw);

                    Arcpy.RepairGeometry(zqfw);

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        #endregion   数据生成

        #region   数据质检
        // 几何错误检查
        private async void btn_geoErr_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【几何错误检查】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string gdb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb";

                        // 获取 矢量数据
                        List<string> fcs = gdb.GetFeatureClassPathFromGDB();

                        foreach (var fc in fcs)
                        {
                            string fcName = fc[(fc.LastIndexOf(@"\") + 1)..].Replace("安溪县", "");

                            // 默认数据库位置
                            Arcpy.CheckGeometry(fc, rd.TemTable);

                            long fCount = rd.TemTable.GetRowCount();

                            // 输出错误信息
                            SolidColorBrush brushes = fCount > 0 ? Brushes.Red : Brushes.Gray;
                            pw.AddMessageMiddle(0, $"           {fcName}_几何错误：{fCount}", brushes);
                        }


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }
        // 1平方米碎图斑
        private async void btn_miniArea_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【1平方米碎图斑】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string gdb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb";

                        // 获取 矢量数据
                        List<string> fcs = gdb.GetFeatureClassPathFromGDB();

                        foreach (var fc in fcs)
                        {
                            string fcName = fc[(fc.LastIndexOf(@"\") + 1)..].Replace("安溪县", "");

                            // 选择
                            Arcpy.Select(fc, rd.TemFC, "Shape_Area < 1");

                            long fCount = rd.TemFC.GetRowCount();

                            // 输出错误信息
                            SolidColorBrush brushes = fCount > 0 ? Brushes.Red : Brushes.Gray;
                            pw.AddMessageMiddle(0, $"           {fcName}_碎图斑：{fCount}", brushes);
                        }


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 多部件检查
        private async void btn_multiPart_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【多部件检查】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string gdb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb";

                        // 获取 矢量数据
                        List<string> fcs = gdb.GetFeatureClassPathFromGDB();

                        foreach (var fc in fcs)
                        {
                            string fcName = fc[(fc.LastIndexOf(@"\") + 1)..].Replace("安溪县", "");

                            int fCount = 0;

                            // 获取原始图层和标识图层的要素类
                            FeatureClass originFeatureClass = fc.TargetFeatureClass();
                            // 获取目标图层和源图层的要素游标
                            using RowCursor originCursor = originFeatureClass.Search();
                            // 遍历源图层的要素
                            while (originCursor.MoveNext())
                            {
                                using Feature feature = (Feature)originCursor.Current;
                                Polygon polygon = feature.GetShape() as Polygon;
                                // 获取面要素的所有点（内外环）
                                List<List<MapPoint>> mapPoints = polygon.MapPointsFromPolygon();

                                List<List<MapPoint>> newPoints = new List<List<MapPoint>>();
                                // 挑选合适的
                                foreach (List<MapPoint> mapPoint in mapPoints)
                                {
                                    // 判断顺逆时针
                                    bool isClockwise = mapPoint.IsColckwise();
                                    if (isClockwise)
                                    {
                                        newPoints.Add(mapPoint);
                                    }
                                }

                                if (newPoints.Count > 1)
                                {
                                    fCount += 1;
                                }

                            }

                            // 输出错误信息
                            SolidColorBrush brushes = fCount > 0 ? Brushes.Red : Brushes.Gray;
                            pw.AddMessageMiddle(0, $"           {fcName}_多部件：{fCount}", brushes);
                        }


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 初始是否都在实体地域内
        private async void btn_cs_inSt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【初始是否都在实体地域内】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string gdb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb";

                        string zqcsfw = $@"{gdb}\安溪县zqcsfw";
                        string zqstdy = $@"{gdb}\安溪县zqstdy";

                        // 擦除
                        string erase = $@"{rd.DefGDB}\in_St_{year}";
                        Arcpy.Erase(zqcsfw, zqstdy, erase);

                        var fCount = erase.GetFeatureCount();

                        // 输出错误信息
                        if (fCount == 0)
                        {
                            pw.AddMessageMiddle(0, $"     不在实体地域内的初始图斑数量：{fCount}", Brushes.Gray);
                        }
                        else
                        {
                            List<double> areas = GisTool.GetDoubleFieldValuesFromPath(erase, "shape_area");
                            double maxArea = areas.Max();
                            pw.AddMessageMiddle(0, $"     不在实体地域内的初始图斑数量：{fCount}，最大面积{maxArea}", Brushes.Red);
                        }


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 初始空洞是否被填充
        private async void btn_cs_hole_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【初始空洞是否被填充】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string gdb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb";

                        string zqcsfw = $@"{gdb}\安溪县zqcsfw";
                        string zqstdy = $@"{gdb}\安溪县zqstdy";

                        // 空洞
                        string cave = $@"{rd.DefGDB}\cave2";
                        ComboTool.GetCave(zqcsfw, cave);

                        // 裁剪
                        string clip_fc = $@"{rd.DefGDB}\cave_{year}";
                        Arcpy.Clip(zqstdy, cave, clip_fc);

                        var fCount = clip_fc.GetFeatureCount();

                        // 输出错误信息
                        if (fCount == 0)
                        {
                            pw.AddMessageMiddle(0, $"     被填充的空洞数量：{fCount}", Brushes.Gray);
                        }
                        else
                        {
                            List<double> areas = GisTool.GetDoubleFieldValuesFromPath(clip_fc, "shape_area");
                            double maxArea = areas.Max();
                            pw.AddMessageMiddle(0, $"     被填充的空洞数量：{fCount}，最大面积{maxArea}", Brushes.Red);
                        }


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 纳入地类是否合规
        private async void btn_dl_inRule_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【初始空洞是否被填充】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string gdb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb";

                        string zqcsfw = $@"{gdb}\安溪县zqcsfw";
                        string zqstdy = $@"{gdb}\安溪县zqstdy";

                        // 擦除
                        string erase2 = $@"{rd.DefGDB}\erase2";
                        Arcpy.Erase(zqstdy, zqcsfw, erase2);
                        // 选择
                        string select2 = $@"{rd.DefGDB}\dlRule_{year}";
                        Arcpy.Select(erase2, select2, "DLBM NOT IN ('0508', '05H1', '0601', '0701', '0702','0809', '0810', '0810A', '08H1', '08H2', '08H2A', '09', '1001','1002', '1003', '1004', '1005', '1006','1007', '1008','1009','1107','1107A',''1109')");

                        var fCount = select2.GetFeatureCount();

                        // 输出错误信息
                        SolidColorBrush brushes = fCount > 0 ? Brushes.Red : Brushes.Gray;
                        pw.AddMessageMiddle(0, $"            不符合地类的图斑数量：{fCount}", brushes);


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }

        // 拓扑重叠检查
        private async void btn_topo_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取参数
                RD rd = GetParams();

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageMiddle(0, $"【拓扑重叠检查】", Brushes.Blue);


                    // 提取指定地类
                    foreach (int year in rd.Years)
                    {
                        pw.AddMessageMiddle(0, $"<{year}>", Brushes.Green);

                        string gdb = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县{year}\1矢量数据\350524安溪县.gdb";

                        // 获取 矢量数据
                        List<string> fcs = gdb.GetFeatureClassPathFromGDB();

                        foreach (var fc in fcs)
                        {
                            string fcName = fc[(fc.LastIndexOf(@"\") + 1)..].Replace("安溪县", "");

                            // 拓扑重叠
                            ComboTool.TopologyCheck(fc, ["Must Not Overlap (Area)"], rd.DefGDB);

                            string polygon = $@"{rd.DefGDB}\TopErr_poly";
                            string polyline = $@"{rd.DefGDB}\TopErr_line";
                            string point = $@"{rd.DefGDB}\TopErr_point";

                            List<string> errs = new List<string>() { polygon, polyline, point };

                            long errCount = 0;

                            foreach (var err in errs)
                            {

                                var fCount = err.GetFeatureCount();

                                errCount += fCount;
                            }

                            // 输出错误信息
                            if (errCount == 0)
                            {
                                pw.AddMessageMiddle(0, $"           {fcName}_拓扑重叠图斑：{errCount}", Brushes.Gray);
                            }
                            else
                            {
                                List<double> areas = GisTool.GetDoubleFieldValuesFromPath(polygon, "shape_area");
                                double maxArea = areas.Max();
                                pw.AddMessageMiddle(0, $"           {fcName}_拓扑重叠图斑：{errCount}，最大面积{maxArea}", Brushes.Red);
                            }

                        }


                    }

                });
                pw.AddMessageEnd();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }


        #endregion   数据质检



        private void openBaseFolderButton_Click(object sender, RoutedEventArgs e)
        {
            textBaseFolderPath.Text = UITool.OpenDialogFolder();
        }

        private void openTargetFolderButton_Click(object sender, RoutedEventArgs e)
        {
            textTargetFolderPath.Text = UITool.OpenDialogFolder();
        }


        // 导出最小统计单元面积数据表
        private void ExportTable(string zqfw, RD rd)
        {
            // 创建一个空元组
            var data = new List<List<string>>();

            // 读取数据
            Table table = zqfw.TargetTable();
            using RowCursor rowCursor = table.Search();
            while (rowCursor.MoveNext())
            {
                Row row = rowCursor.Current;
                string JCWMC = row["JCWMC"]?.ToString() ?? "";
                string JCWDM = row["JCWDM"]?.ToString() ?? "";
                string ZDDLMJ = row["ZDDLMJ"]?.ToString() ?? "";
                string STDYMJ = row["STDYMJ"]?.ToString() ?? "";
                string MJZB = row["MJZB"]?.ToString() ?? "";
                // 筛选非空值
                if (MJZB != "")
                {
                    data.Add([JCWMC, JCWDM, ZDDLMJ, STDYMJ, MJZB]);
                }
            }
            // 将data的子项的第5项转换为数字后排序
            data.Sort((x, y) => -double.Parse(x[4]).CompareTo(double.Parse(y[4])));


            string model_excel = $@"{rd.BaseFolderPath}\350524安溪县最小统计单元面积数据表.xls";
            string excelPath = $@"{rd.TargetFolderPath}\350524安溪县\350524安溪县2021\2统计数据\350524安溪县最小统计单元面积数据表.xls";
            // 复制模板
            File.Copy(model_excel, excelPath, true);

            // 打开excel表
            // 获取工作薄、工作表
            string excelFile = ExcelTool.GetPath(excelPath);
            int sheetIndex = ExcelTool.GetSheetIndex(excelPath);
            // 打开工作薄
            Workbook wb = ExcelTool.OpenWorkbook(excelFile);
            // 打开工作表
            Worksheet sheet = wb.Worksheets[sheetIndex];

            Cells cells = sheet.Cells;

            for (int i = 0; i < data.Count; i++)
            {
                //  第二行开始复制行
                if (i > 0)
                {
                    cells.CopyRow(cells, 1, i + 1);
                }

                var rowValues = data[i];
                cells[i + 1, 0].Value = i + 1;
                cells[i + 1, 1].Value = rowValues[0];
                cells[i + 1, 2].Value = rowValues[1];
                cells[i + 1, 3].Value = Math.Round(rowValues[2].ToDouble(), 2);
                cells[i + 1, 4].Value = Math.Round(rowValues[3].ToDouble(), 2);
                cells[i + 1, 5].Value = Math.Round(rowValues[4].ToDouble(), 2);
            }

            // 保存
            wb.Save(excelFile);
            wb.Dispose();




        }

    }

    // 参数
    public class RD
    {
        public string BaseFolderPath { get; set; }
        public string TargetFolderPath { get; set; }
        public bool Is_2021 { get; set; }
        public List<int> Years { get; set; }
        public string DefGDB { get; set; }
        public string TemFC { get; set; }
        public string TemTable { get; set; }

    }
}